﻿using NewsReader.Helpers;
using NewsReader.Log;
using NewsReader.ViewModels;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Linq;
using Windows.ApplicationModel.Background;

namespace NewsReaderTasks
{
    public sealed class LoadFeedsTask : IBackgroundTask
    {
        private BackgroundTaskDeferral _deferral;

        public LoadFeedsTask()
        {
            // First time execution, initialize the logger
            EventListener verboseListener = new StorageFileEventListener("VerboseListener");
            verboseListener.EnableEvents(Logger.Log, EventLevel.Verbose);
        }
        
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            taskInstance.Canceled += (sender, reason) =>
                {
                    Logger.Log.Warn(string.Format("Cancelation of task was requested due to {0}", reason.ToString()));
                };

            Logger.Log.Info("Background Task started");
            if (!ViewModelHelper.IsConnected)
            {
                Logger.Log.Debug("Internet was NOT connected - exiting");

                return;
            }

            Logger.Log.Debug("Internet was connected");


            _deferral = taskInstance.GetDeferral();
            Logger.Log.Debug("Got Deferral");

#if DEBUG
            var stopWatch = new Stopwatch();
            stopWatch.Start();
#endif
            try
            {

                var uris = PersistenceHelper.GetUserFeedsAsync().AsTask().Result;

#if DEBUG
            long time = stopWatch.ElapsedMilliseconds;
            Logger.Log.DebugFormat("Got all uris took {0} mlliseconds or {1} seconds", time, TimeSpan.FromMilliseconds(time).TotalSeconds);
#endif
                var uriCount = uris.Count();
                Logger.Log.Debug(string.Format("Got {0} uris from the user feed table.", uriCount));

                uint uriProgress = 0;

                if (uriCount > 0)
                {
                    uriProgress = (uint)(80 / uriCount);
                }
                var feeds = new List<FeedInfo>();

                foreach (var fc in uris)
                {
                    try
                    {
                        Logger.Log.Info(string.Format("Loading feed titled {0} with uri {1}", fc.Title, fc.Uri));
                        var fi = new FeedInfo(fc.Title, fc.Uri);

#if DEBUG
                    time = stopWatch.ElapsedMilliseconds;
                    Logger.Log.DebugFormat("Created FeedInfo {0} took {1} mlliseconds or {2} seconds", fc.Title, time, TimeSpan.FromMilliseconds(time).TotalSeconds);
#endif
                        Logger.Log.Debug("Begin loading NonGUI");
                        var task = fi.LoadNonGUI();
                        task.Wait();
                        Logger.Log.Debug("Completed loading NonGUI");

#if DEBUG
                    time = stopWatch.ElapsedMilliseconds;
                    Debug.WriteLine("Loaded FeedInfo {0} took {1} mlliseconds or {2} seconds", fc.Title, time, TimeSpan.FromMilliseconds(time).TotalSeconds);
#endif

                        feeds.Add(fi);
                        taskInstance.Progress += uriProgress;
                        Logger.Log.Info(string.Format("Progress is now {0}", taskInstance.Progress));
                    }
                    catch (Exception ex)
                    {
                        Logger.Log.Error(string.Format("Error occurred. Exception {0}.", ex));
                    }
                }

                taskInstance.Progress = 80;
                Logger.Log.Info("Saving feeds to DB");
                PersistenceHelper.SaveFeedsToDB(feeds);
                taskInstance.Progress = 100;
                Logger.Log.Info("Progress is now 100");

#if DEBUG
            time = stopWatch.ElapsedMilliseconds;
            Logger.Log.DebugFormat("Task took {0} mlliseconds or {1} seconds", time,
                TimeSpan.FromMilliseconds(time).TotalSeconds);
#endif
            }

            catch (Exception ex)
            {
                Logger.Log.Error(string.Format("Error occurred running code. Exception {0}.", ex));
            }

            finally
            {
                _deferral.Complete();
            }
        }

    }
}